package com.example.myapplication.decoration;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.LayoutManager;
import androidx.recyclerview.widget.RecyclerView.State;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import java.util.Objects;

public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {

    private final Context mContext;
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private final Drawable mDivider;
    private final boolean hasFooter;
    private final Paint mPaint;
    private int mColorResId;
    private int preHorizontalBottom;
    private int mHorizontalLineWidth = 0;
    private int mVerticalLineWidth = 0;

    public DividerGridItemDecoration(Context context) {
        this(context, false);
    }

    /**
     * @param hasFooter 是否有脚部
     */
    public DividerGridItemDecoration(Context context, boolean hasFooter) {
        mContext = context;
        this.hasFooter = hasFooter;
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        mPaint = new Paint();
    }

    public DividerGridItemDecoration colorResId(@ColorRes int resId) {
        mColorResId = resId;
        return this;
    }

    //设置水平分割线的宽度
    public DividerGridItemDecoration widthResId(@DimenRes int resId) {
        mHorizontalLineWidth = mContext.getResources().getDimensionPixelSize(resId);
        return this;
    }

    //设置垂直分割线的宽度
    public DividerGridItemDecoration widthOfVerticalResId(@DimenRes int resId) {
        mVerticalLineWidth = mContext.getResources().getDimensionPixelSize(resId);
        return this;
    }

    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {
        drawHorizontal(c, parent);
        drawVertical(c, parent);
    }

    private int getSpanCount(RecyclerView parent) {
        // 列数
        int spanCount = -1;
        LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {

            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager)
                    .getSpanCount();
        }
        return spanCount;
    }

    private void drawHorizontal(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            // 有脚部时，最后一条不画
            if (hasFooter &&
                    parent.getChildLayoutPosition(child) == Objects.requireNonNull(parent.getLayoutManager()).getItemCount() - 1) {
                continue;
            }

            if (mHorizontalLineWidth > 0) {
                if (mColorResId > 0) {
                    mPaint.setColor(ContextCompat.getColor(mContext, mColorResId));
                    mPaint.setStrokeWidth(mHorizontalLineWidth);
                    if (preHorizontalBottom - child.getBottom() != 0 && Math.abs(preHorizontalBottom - child.getBottom()) < 10) {
                        // 一行的最后一个的bottom莫名小了3px
                        c.drawLine(child.getLeft() - mHorizontalLineWidth, preHorizontalBottom + mHorizontalLineWidth / 2f, child.getRight() + mHorizontalLineWidth, preHorizontalBottom + mHorizontalLineWidth / 2f, mPaint);
                    } else {
                        preHorizontalBottom = child.getBottom();
                        c.drawLine(child.getLeft() - mHorizontalLineWidth, child.getBottom() + mHorizontalLineWidth / 2f, child.getRight() + mHorizontalLineWidth, child.getBottom() + mHorizontalLineWidth / 2f, mPaint);
                    }
                } else {
                    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                            .getLayoutParams();
                    int left = child.getLeft() - params.leftMargin;
                    int right = child.getRight() + params.rightMargin
                            + mDivider.getIntrinsicWidth();
                    int top = child.getBottom() + params.bottomMargin;
                    int bottom = top + mDivider.getIntrinsicHeight();
                    mDivider.setBounds(left, top, right, bottom + mHorizontalLineWidth);
                    mDivider.draw(c);
                }
            }
        }
    }

    private void drawVertical(Canvas c, RecyclerView parent) {
        final int childCount = parent.getChildCount();
        int span = getSpanCount(parent);
        for (int i = 0; i < childCount; i++) {
            if (i % span == span - 1)
                continue;
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getTop() - params.topMargin;
            final int bottom = child.getBottom() + params.bottomMargin;
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicWidth();

            if (mVerticalLineWidth > 0) {
                if (mColorResId > 0) {
                    mPaint.setColor(ContextCompat.getColor(mContext, mColorResId));
                    mPaint.setStrokeWidth(mVerticalLineWidth);
                    c.drawLine(child.getRight() + mVerticalLineWidth / (float)2, child.getTop() - mVerticalLineWidth,
                            child.getRight() + mVerticalLineWidth / (float)2, child.getBottom() + mVerticalLineWidth, mPaint);
                } else {
                    mDivider.setBounds(left, top, right + mVerticalLineWidth, bottom);
                    mDivider.draw(c);
                }
            }
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, @NonNull RecyclerView parent, @NonNull State state) {
        int span = getSpanCount(parent);
        int padding = mVerticalLineWidth / span;
        int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
        int columnIndex = itemPosition % span;
        int rowIndex = itemPosition / span;
        outRect.left = columnIndex * padding;
        outRect.right = mVerticalLineWidth - outRect.left - padding;
        if (rowIndex != 0)
            outRect.top = Math.max(mHorizontalLineWidth, 0);
        else
            outRect.top = 0;
        outRect.bottom = 0;
    }
}
